home *** CD-ROM | disk | FTP | other *** search
- #
- # This file is part of OpenVIP (http://openvip.sourceforge.net)
- #
- # Copyright (C) 2002-2003
- # Michal Dvorak, Jiri Sedlar, Antonin Slavik, Vaclav Slavik, Jozef Smizansky
- #
- # This program is licensed under GNU General Public License version 2;
- # see file COPYING in the top level directory for details.
- #
- # $Id: logging.py,v 1.12 2003/06/03 21:01:13 vaclavslavik Exp $
- #
- # Classes for logging and progress indication
- #
-
- import openvip
- import thread
- from wxPython.wx import *
- import App
-
- _mainThreadID = thread.get_ident()
-
-
- # --------------------------------------------------------------------
- # Progress bar widgets:
- # --------------------------------------------------------------------
-
- class GaugeMixin:
- def OnCancel(self, event):
- self.cancelled = True
- self.cancel.Enable(False)
- def update(self, value):
- self.progress.SetValue(int(100*value))
- if self.exclusive:
- wxGetApp().Yield(True)
- return not self.cancelled
- def info(self, msg):
- self.infostr.SetLabel(msg)
- def stop(self):
- self.Destroy()
-
- class BigGauge(wxDialog, GaugeMixin):
- def __init__(self, exclusive=True, cancellable=True):
- self.exclusive = exclusive
- self.cancellable = cancellable
- wxDialog.__init__(self, App.mainFrame, -1, 'Progress')
- self.infostr = wxStaticText(self, -1, '')
- self.progress = wxGauge(self, -1, 100,
- size=(300,-1),
- style=wxGA_SMOOTH|wxGA_HORIZONTAL)
- sizer = wxBoxSizer(wxVERTICAL)
- sizer.Add(self.infostr, 0, wxEXPAND | wxALL, 5)
- sizer.Add(self.progress, 0, wxEXPAND | wxALL, 5)
- if cancellable:
- self.cancel = wxButton(self, wxID_CANCEL, 'Cancel')
- sizer.Add(self.cancel, 0, wxALIGN_RIGHT | wxALL, 10)
- EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
- self.SetSizer(sizer)
- sizer.SetSizeHints(self)
- sizer.Fit(self)
- self.SetAutoLayout(True)
- self.cancelled = False
- self.Show(True)
- if exclusive:
- self.disabler = wxWindowDisabler(self)
-
- class StatusbarGauge(wxDialog, GaugeMixin):
- def __init__(self, cancellable=True):
- self.exclusive = False
- self.cancellable = cancellable
- wxDialog.__init__(self, App.mainFrame, -1, 'Progress')
- self.infostr = wxStaticText(self, -1, '', size=(80,-1),
- style=wxST_NO_AUTORESIZE)
- self.progress = wxGauge(self, -1, 100,
- size=(150,-1),
- style=wxGA_SMOOTH|wxGA_HORIZONTAL)
- sizer = wxBoxSizer(wxHORIZONTAL)
- sizer.Add(self.infostr, 0, wxALIGN_CENTRE_VERTICAL|wxALL, 1)
- sizer.Add(self.progress, 1, wxEXPAND | wxALL, 1)
- if cancellable:
- self.cancel = wxButton(self, wxID_CANCEL, 'X',
- style=wxBU_EXACTFIT)
- sizer.Add(self.cancel, 0, wxEXPAND | wxALL, 1)
- EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
- self.SetSizer(sizer)
- sizer.SetSizeHints(self)
- sizer.Fit(self)
- self.SetAutoLayout(True)
- self.cancelled = False
- self.Show(True)
-
-
- # --------------------------------------------------------------------
- # UI callback class and event, for multithreaded progress info:
- # --------------------------------------------------------------------
-
- wxEVT_PROGRESS_UPDATE = wxNewEventType()
-
- def EVT_PROGRESS_UPDATE(win, func):
- win.Connect(-1, -1, wxEVT_PROGRESS_UPDATE, func)
-
- class ProgressUpdateEvent(wxPyEvent):
- def __init__(self, func, arg):
- wxPyEvent.__init__(self)
- self.SetEventType(wxEVT_PROGRESS_UPDATE)
- self.func = func
- self.arg = arg
-
- class UICallbackEvtHandler(wxEvtHandler):
- def __init__(self, parent):
- wxEvtHandler.__init__(self)
- EVT_PROGRESS_UPDATE(self, self.OnUpdate)
- self.parent = parent
- def OnUpdate(self, event):
- if event.func != None:
- event.func(event.arg)
- else:
- self.parent.UpdateGauge()
-
-
- # --------------------------------------------------------------------
- # UI callback class:
- # --------------------------------------------------------------------
-
- def _mainThread():
- return thread.get_ident() == _mainThreadID
-
- class Status:
- def __init__(self):
- self.value = 0.0
- self.shown = False
- self.text = ''
-
- class UICallback(openvip.UICallback):
- """This is openvip.UICallback implementation suitable for use in
- wxPython applications."""
- def __init__(self,
- background=False, docked=False, cancellable=False,
- progress=True):
- """Ctor.
- background: for use with background renderer
- cancellable: the user can cancel operation
- docked: use more compact 'docked' version of progress bar
- progress: show progressbar? (Otherwise only logging is done.)
- """
- self.gauge = None
- self.progress = progress
- self.handler = UICallbackEvtHandler(self)
- self.keepGoing = True
- self.background = background
- self.docked = docked
- self.cancellable = cancellable
- self.gaugeStatus = Status()
-
- def show_gauge(self):
- if not self.progress: return
- self.gaugeStatus.shown = True
- if _mainThread(): self.UpdateGauge()
- else: self.__postEvent()
-
- def update_gauge(self, value):
- if not self.progress: return
- self.gaugeStatus.value = value
- if _mainThread(): self.UpdateGauge()
- else: self.__postEvent()
- return self.keepGoing
-
- def hide_gauge(self):
- if not self.progress: return
- self.gaugeStatus.shown = False
- if _mainThread(): self.UpdateGauge()
- else: self.__postEvent()
-
- def set_gauge_text(self, msg):
- if not self.progress: return
- if _mainThread():
- self.gauge.info(msg)
- else:
- self.__postEvent(self.set_gauge_text, msg)
-
- def log_info(self, msg):
- if _mainThread():
- wxLogVerbose(msg)
- else:
- self.__postEvent(self.log_info, msg)
-
- def log_error(self, msg):
- if _mainThread():
- wxLogError(msg)
- else:
- self.__postEvent(self.log_error, msg)
-
- def log_warning(self, msg):
- if _mainThread():
- wxLogWarning(msg)
- else:
- self.__postEvent(self.log_warning, msg)
-
- def __postEvent(self, func=None, arg=None):
- evt = ProgressUpdateEvent(func, arg)
- wxPostEvent(self.handler, evt)
-
- def UpdateGauge(self):
- if self.gauge == None and self.gaugeStatus.shown:
- if self.docked:
- self.gauge = StatusbarGauge(cancellable=self.cancellable)
- else:
- self.gauge = BigGauge(cancellable=self.cancellable,
- exclusive=not self.background)
- if self.gauge != None:
- self.keepGoing = self.gauge.update(self.gaugeStatus.value)
- if self.gauge != None and (not self.gaugeStatus.shown):
- self.gauge.stop()
- self.gauge = None
-
-
-
-
-
- # --------------------------------------------------------------------
- # Testing code
- # --------------------------------------------------------------------
- if __name__ == '__main__':
- import sys, thread
- def work(x,y,f=None):
- x.show_gauge()
- for i in range(y):
- x.set_gauge_text('Working: %i %%' % i)
- if not x.update_gauge(float(i)/y):
- break
- wxUsleep(40)
- if f!=None:f()
- x.hide_gauge()
- class MyApp(wxApp):
- def OnInit(self):
- t = (UICallback(docked=True,background=True),100)
- thread.start_new_thread(work, t)
- x=UICallback(cancellable=True)
- work(x,400, wxYield)
- return False
- app = MyApp(0)
- app.MainLoop()
-